package org.jeecg.modules.paycenter.pay.util;


import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.paycenter.channel.bankdocking.service.NhBankService;
import org.jeecg.modules.paycenter.pay.dto.PayBillData;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.UUID;


@Component
public class OldPayUtil {

    private RabbitTemplate rabbitTemplate;
    @Autowired
    private NhBankService bankService;

    @Value(value = "${jeecg.path.paylogpath}")
    public String logpath;

    public OldPayUtil(@Autowired RabbitTemplate rt) {
        this.rabbitTemplate = rt;
        rabbitTemplate.setEncoding("UTF-8");
        //设置手工ack确认
        rabbitTemplate.setMandatory(true);

        /**
         * 如果消息没有到exchange,则confirm回调,ack=false
         * 如果消息到达exchange,则confirm回调,ack=true
         * 这里就是确认消息的回调监听接口，用于确认消息是否被broker所收到,消息只要被 rabbitmq broker 接收到就会触发 confirmCallback 回调
         */
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             *
             * @param correlationData 对象内部只有一个 id 属性，用来表示当前消息的唯一性。
             * @param ack 消息投递到broker 的状态，true表示成功。
             * @param cause 表示投递失败的原因。
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                if (!ack) {
                    try {
                        String jsonData = new String(correlationData.getReturnedMessage().getBody(), "utf-8");
                        PayBillData payBillData = JSON.parseObject(jsonData, PayBillData.class);
                        OldPayUtil.this.savePayFail(payBillData);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        //exchange到queue成功,则不回调return
        //exchange到queue失败,则回调return
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {

            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                try {
                    String jsonData = new String(message.getBody(), "utf-8");
                    PayBillData payBillData = JSON.parseObject(jsonData, PayBillData.class);
                    OldPayUtil.this.savePayFail(payBillData);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void savePayFail(PayBillData payBillData) {
        try {
            payBillData.getShippingNote().setShippingPayStatus("7");
            bankService.savePayFailInfo(payBillData);
        } catch (Exception ex) {
            //保存到文件,人工处理
            String s = JSON.toJSONString(payBillData);
            String dateString = DateUtils.getDate("yyyyMMddHHmmssSSS");
            String fileName = "fail_pay_" + payBillData.getShippingNote().getId() + "_" + dateString;
            saveToFile(s, fileName);
        }
    }

    private void saveToFile(String content, String fileName) {
        try {
            String filePath = this.logpath + fileName;
            FileUtil.writeUtf8String(content, filePath);
        } catch (Exception e) {
            System.err.println(e);
        }
    }

    public void postBillPay(PayBillData payData) {
        String jsonData = JSON.toJSONString(payData);
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend("billPayCenterExchange", "billPayCenter", jsonData,
                message -> {
                    message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                    return message;
                }
                , correlationData);
    }

    public void billPay(String  billId) {
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend("payCenterExchange", "payCenter", billId,
                message -> {
                    message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                    return message;
                }
                , correlationData);
    }


}
